<template>
  <div class="role-manage">
    <div class="query-form">
      <el-form ref="form" :inline="true" :model="queryForm">
        <el-form-item label="角色名称" prop="roleName">
          <el-input v-model="queryForm.roleName" placeholder="请输入角色名称" />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="getRoleList">查询</el-button>
          <el-button @click="handleReset('form')">重置</el-button>
        </el-form-item>
      </el-form>
    </div>
    <div class="base-table">
      <div class="action">
        <el-button v-has="'role-create'"  type="primary" @click="handleAdd">创建</el-button>
      </div>
      <el-table :data="roleList">
        <el-table-column
          v-for="item in columns"
          :key="item.prop"
          :prop="item.prop"
          :label="item.label"
          :width="item.width"
          :formatter="item.formatter"
        >
        </el-table-column>
        <el-table-column label="操作" width="260">
          <template #default="scope">
            <el-button size="small" @click="handleEdit(scope.row)"
            v-has="'role-edit'" 
              >编辑</el-button
            >
            <el-button
              size="small"
              type="primary"
              @click="handleOpenPermission(scope.row)"
              v-has="'role-set'" 
              >设置权限</el-button
            >
            <el-button
              type="danger"
              size="small"
              @click="handleDel(scope.row._id)"
              v-has="'role-delete'" 
              >删除</el-button
            >
          </template>
        </el-table-column>
      </el-table>
      <el-pagination
        class="pagination"
        background
        layout="prev, pager, next"
        :total="pager.total"
        :page-size="pager.pageSize"
        @current-change="handleCurrentChange"
      />
    </div>
    <el-dialog title="角色新增" v-model="showModal">
      <el-form
        ref="dialogForm"
        :model="roleForm"
        label-width="100px"
        :rules="rules"
      >
        <el-form-item label="角色名称" prop="roleName">
          <el-input v-model="roleForm.roleName" placeholder="请输入角色名称" />
        </el-form-item>
        <el-form-item label="备注" prop="remark">
          <el-input
            type="textarea"
            :rows="2"
            v-model="roleForm.remark"
            placeholder="请输入备注"
          />
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="handleClose">取 消</el-button>
          <el-button type="primary" @click="handleSubmit">确 定</el-button>
        </span>
      </template>
    </el-dialog>
    <!-- 权限弹框-->
    <el-dialog title="权限设置" v-model="showPermission">
      <el-form label-width="100px">
        <el-form-item label="角色名称">
          {{ curRoleName }}
        </el-form-item>
        <el-form-item label="选择权限">
          <el-tree
            ref="tree"
            :data="menuList"
            show-checkbox
            node-key="_id"
            default-expand-all
            :props="{ label: 'menuName' }"
          >
          </el-tree>
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="showPermission = false">取 消</el-button>
          <el-button type="primary" @click="handlePermissionSubmit"
            >确 定</el-button
          >
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted, getCurrentInstance } from 'vue'
import utils from '../utils/utils'

const { proxy } = getCurrentInstance()

const queryForm = reactive({
  roleName: '',
})

const form = ref('')
const dialogForm = ref('')
const columns = ref([
  {
    label: '角色名称',
    prop: 'roleName',
  },
  {
    label: '备注',
    prop: 'remark',
  },
  {
    label: '权限列表',
    prop: 'permissionList',
    width: 300,
    formatter: (row, column, value) => {
      let names = []
      let list = value.halfCheckedKeys || []
      list.map((key) => {
        let name = actionMap[key]
        if (key && name) names.push(name)
      })
      return names.join(',')
    },
  },
  {
    label: '更新时间',
    prop: 'updateTime',
    formatter(row, column, value) {
      return utils.formateDate(new Date(value))
    },
  },
  {
    label: '创建时间',
    prop: 'createTime',
    formatter(row, column, value) {
      return utils.formateDate(new Date(value))
    },
  },
])
const roleList = ref([])
const pager = reactive({
  total: 0,
  pageNum: 1,
  pageSize: 10,
})
const showModal = ref(false)
const action = ref('create')
const roleForm = reactive({})
const rules = reactive({
  roleName: [
    {
      required: true,
      message: '请输入角色角色名称',
    },
  ],
})

// 权限展示
const showPermission = ref(false)
const curRoleId = ref('')
const curRoleName = ref('')
const menuList = ref([])
// 菜单映射表
const actionMap = reactive({})

// 角色列表初始化
const getRoleList = async () => {
  try {
    let { list, page } = await proxy.$api.getRoleList({
      ...queryForm,
      ...pager,
    })
    roleList.value = list
    pager.total = page.total
  } catch (e) {
    throw new Error(e)
  }
}
// 菜单列表初始化
const getMenuList = async() => {
  try {
    let list = await proxy.$api.getMenuList()
    menuList.value = list
    getActionMap(list)
  } catch (error) {
    throw new Error(error)
  }
}

// 表单重置
const handleReset = (form) => {
  proxy.$refs[form].resetFields()
}

// 角色添加
const handleAdd = () => {
  action.value = 'create'
  showModal.value = true
}

// 角色编辑
const handleEdit = (row) => {
  action.value = 'edit'
  showModal.value = true
  proxy.$nextTick(() => {
    Object.assign(roleForm, row)
  })
}
// 角色删除
const handleDel = async (_id) => {
  await proxy.$api.roleOperate({ _id, aciton: 'delete' })
  proxy.$message.success('删除成功')
  getRoleList()
}
// 弹框关闭
const handleClose = () => {
  handleReset('dialogForm')
  showModal.value = false
}
// 角色提交
const handleSubmit = () => {
  dialogForm.value.validate(async (valid) => {
    if (valid) {
      let { roleForm, action } = proxy
      let params = { ...roleForm, action }
      let res = await proxy.$api.roleOperate(params)
      if (res) {
        showModal.value = false
        proxy.$message.success('操作成功')
        handleReset('dialogForm')
        getRoleList()
      }
    }
  })
}

const handleCurrentChange = current => {
  pager.pageNum = current
  getRoleList()
}

const handleOpenPermission = (row) => {
  curRoleId.value = row._id
  curRoleName.value = row.roleName
  showPermission.value = true
  let { checkedKeys } = row.permissionList
  proxy.$nextTick(() => {
    proxy.$refs.tree.setCheckedKeys(checkedKeys)
  })
}

const handlePermissionSubmit =async() => {
  let nodes = proxy.$refs.tree.getCheckedNodes()
  let halfKeys = proxy.$refs.tree.getHalfCheckedKeys()
  let checkedKeys = []
  let parentKeys = []
  nodes.map(node => {
    if(!node.children) {
      checkedKeys.push(node._id)
    }else {
      parentKeys.push(node._id)
    }
  })

  let params = {
    _id: curRoleId.value,
    permissionList: {
      checkedKeys,
      halfCheckedKeys: parentKeys.concat(halfKeys)
    }
  }

  await proxy.$api.updatePermission(params)
  showPermission.value = false
  proxy.$message.success('设置成功')
  getRoleList()
}

const getActionMap = (list) => {
  let mapAction = {}
  const deep = arr => {
    while(arr.length) {
      let item = arr.pop()
      if(item.children && item.action) {
        mapAction[item._id] = item.menuName
      }
      if(item.children && !item.action) {
        deep(item.children)
      }
    }
  }
  deep(JSON.parse(JSON.stringify(list)))
  Object.assign(actionMap, mapAction)
}

onMounted(() => {
  getRoleList()
  getMenuList()
})
</script>

<style></style>
